﻿using Newtonsoft.Json.Linq;
using SDWXServer.Models;
using Senparc.NeuChar.Context;
using Senparc.NeuChar.Entities;
using Senparc.Weixin.MP;
using Senparc.Weixin.MP.Containers;
using Senparc.Weixin.MP.Entities;
using Senparc.Weixin.MP.Entities.Menu;
using Senparc.Weixin.MP.Entities.Request;
using Senparc.Weixin.MP.MessageHandlers;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;

namespace SDWXServer.Controllers
{
    public class WRZSMessageHandler : MessageHandler<MessageContext<IRequestMessageBase, IResponseMessageBase>>
    {
        public WRZSMessageHandler(Stream inputStream, PostModel postModel, int maxRecordCount = 0)
            : base(inputStream, postModel, maxRecordCount)
        {

        }
        public override IResponseMessageBase DefaultResponseMessage(IRequestMessageBase requestMessage)
        {
            //ResponseMessageText也可以是News等其他类型
            var responseMessage = this.CreateResponseMessage<ResponseMessageText>();
            responseMessage.Content = "";

            return responseMessage;
        }
        public override IResponseMessageBase OnEventRequest(IRequestMessageEventBase requestMessage)
        {
            if (requestMessage.EventName == "ENTER")
            {
                CacheMPUser(requestMessage.FromUserName);
            }

            return base.OnEventRequest(requestMessage);
        }

        public override IResponseMessageBase OnTextRequest(RequestMessageText requestMessage)
        {
            CacheMPUser(requestMessage.FromUserName);

            //TODO:这里的逻辑可以交给Service处理具体信息，参考OnLocationRequest方法或/Service/LocationSercice.cs
            var responseMessage = CreateResponseMessage<ResponseMessageText>();
            if (requestMessage.Content == "wrzsmenuupdate")
            {
                CreateOrUpdateMPMenu();
                responseMessage.Content = "已尝试更新公众号菜单";
            }
            else if (requestMessage.Content == "openid")
            {
                responseMessage.Content = string.Format("您的openid是：{0}", requestMessage.FromUserName);
            }
            else if (requestMessage.Content == "me")
            {
                responseMessage.Content = GetUserInfo(requestMessage.FromUserName);
            }
            else
            {
                responseMessage.Content = string.Format(
                        "您刚才发送了文字信息：{0}\r\n您还可以发送【位置】【图片】【语音】等类型的信息，查看不同格式的回复。",
                        requestMessage.Content);
            }

            return responseMessage;
        }

        public override IResponseMessageBase OnEvent_SubscribeRequest(RequestMessageEvent_Subscribe requestMessage)
        {
            CacheMPUser(requestMessage.FromUserName);

            var responseMessage = this.CreateResponseMessage<ResponseMessageText>();
            responseMessage.Content = KD.LoginViewModel.Current.WeixinAppSubscribeMessage;

            return responseMessage;
        }

        //更多没有重写的OnXX方法，将默认返回DefaultResponseMessage中的结果。

        private void CreateOrUpdateMPMenu()
        {
            try
            {
                var appId = Senparc.Weixin.Config.SenparcWeixinSetting.WeixinAppId;
                var appSecret = Senparc.Weixin.Config.SenparcWeixinSetting.WeixinAppSecret;
                if (string.IsNullOrWhiteSpace(appId)) return;

                var accessToken = Senparc.Weixin.MP.Containers.AccessTokenContainer.TryGetAccessToken(appId, appSecret);
                var wxOpenAppId = Senparc.Weixin.Config.SenparcWeixinSetting.WxOpenAppId;

                var menuJson = new JObject();
                var appID = System.Configuration.ConfigurationManager.AppSettings.Get("AppID");

                var fullJson = new JObject();
                menuJson["menu"] = fullJson;
                var buttons = new JArray();
                fullJson["button"] = buttons;
                var menu1 = new JObject();
                menu1["type"] = "miniprogram";
                menu1["name"] = "物资门户";
                menu1["url"] = "https://wx.shundoo.net/k3cloud";
                menu1["appid"] = wxOpenAppId;
                menu1["pagepath"] = "pages/materialportal/materialportal";
                buttons.Add(menu1);

                var menu2 = new JObject();
                menu2["type"] = "miniprogram";
                menu2["name"] = "安全环保";
                menu2["url"] = "https://wx.shundoo.net/k3cloud";
                menu2["appid"] = wxOpenAppId;
                menu2["pagepath"] = "pages/safeportal/safeportal";
                buttons.Add(menu2);

                var menu3 = new JObject();
                menu3["type"] = "miniprogram";
                menu3["name"] = "现场管理";
                menu3["url"] = "https://wx.shundoo.net/k3cloud";
                menu3["appid"] = wxOpenAppId;
                menu3["pagepath"] = "pages/sceneportal/sceneportal";
                buttons.Add(menu3);

                var resultFull = Newtonsoft.Json.JsonConvert.DeserializeObject<GetMenuResultFull>(menuJson.ToString());
                var buttonGroup = Senparc.Weixin.MP.CommonAPIs.CommonApi.GetMenuFromJsonResult(resultFull, new ButtonGroup()).menu;
                var result = Senparc.Weixin.MP.CommonAPIs.CommonApi.CreateMenu(accessToken, buttonGroup);
                if (result.errmsg == "ok")
                {
                    KD.Logger.Info("公众号菜单：更新成功");
                }
                else
                {
                    KD.Logger.Info("公众号菜单：{0}", result.errmsg);
                }
            }
            catch (Exception e)
            {
                KD.Logger.Info("公众号菜单", e);
            }
        }
        private void CacheMPUser(string mpOpenId)
        {
            Action action = () =>
            {
                try
                {
                    if (string.IsNullOrWhiteSpace(mpOpenId)) return;

                    WXUser user = null;
                    var userToken = RedisManager.GetValue<string>(mpOpenId);
                    if (string.IsNullOrWhiteSpace(userToken) == false)
                    {
                        user = RedisManager.GetObject<WXUser>(userToken);
                    }

                    if (user == null)
                    {
                        user = new WXUser();
                        user.Id = Guid.NewGuid().ToString();
                        user.MPOpenId = mpOpenId;
                    }
                    if (string.IsNullOrWhiteSpace(user.Id))
                    {
                        user.Id = Guid.NewGuid().ToString();
                    }
                    if (string.IsNullOrWhiteSpace(user.MPOpenId))
                    {
                        user.MPOpenId = mpOpenId;
                    }

                    if (string.IsNullOrWhiteSpace(user.UnionID))
                    {
                        var appId = Senparc.Weixin.Config.SenparcWeixinSetting.WeixinAppId;
                        var appSecret = Senparc.Weixin.Config.SenparcWeixinSetting.WeixinAppSecret;
                        var accessToken = Senparc.Weixin.MP.Containers.AccessTokenContainer.TryGetAccessToken(appId, appSecret);
                        var userInfo = Senparc.Weixin.MP.AdvancedAPIs.UserApi.Info(accessToken, user.MPOpenId);
                        user.UnionID = userInfo.unionid;
                    }
                    var newToken = RedisManager.GetValue<string>(user.UnionID);
                    var newUser = RedisManager.GetObject<WXUser>(newToken);
                    if (newUser != null)
                    {
                        newUser.UnionID = user.UnionID;
                        newUser.MPOpenId = user.MPOpenId;

                        user = newUser;
                    }

                    RedisManager.SetObject<WXUser>(user);
                    RedisManager.SetValue<string>(user.MPOpenId, user.Id);
                    if (string.IsNullOrWhiteSpace(user.UnionID) == false)
                    {
                        RedisManager.SetValue<string>(user.UnionID, user.Id);
                    }
                }
                catch (Exception e)
                {
                    KD.Logger.Info("公众号用户信息", e);
                }
            };
            Kingdee.BOS.KDThread.MainWorker.QuequeTask(action, (asynResult) => { });
        }
        private string GetUserInfo(string mpOpenId)
        {
            var message = "";
            try
            {
                WXUser user = null;
                var userToken = RedisManager.GetValue<string>(mpOpenId);
                if (string.IsNullOrWhiteSpace(userToken) == false)
                {
                    user = RedisManager.GetObject<WXUser>(userToken);

                    if (user != null)
                    {
                        var obj = JObject.FromObject(user);
                        message = obj.ToString();
                    }
                }

                if (string.IsNullOrWhiteSpace(message)) message = "没有找到用户信息";
            }
            catch (Exception e)
            {
                message = e.Message;
            }

            return message;
        }
    }
}